<?php

namespace StudyBuddy\Controllers;

use \StudyBuddy\WebPage;
use \StudyBuddy\MongoDoc;
use \StudyBuddy\Captcha;
use \StudyBuddy\String;
use \StudyBuddy\Api\Clientdata;
use \StudyBuddy\Api\IconParser;
use \StudyBuddy\Request;
use \StudyBuddy\Responder;

/**
 * Controller for Adding
 * or Editing the API Client App
 *
 */
class Editapp extends WebPage
{

	/**
	 * Pre-check to deny non-logged in user
	 * access to this page
	 *
	 * @var bool
	 */
	protected $membersOnly = true;


	/**
	 *
	 * Viewer must have edit_profile
	 * permission to access this page
	 * @var string
	 */
	protected $permission = 'edit_profile';


	/**
	 * $layoutID 1 means no side-column on page
	 *
	 * @var int
	 */
	protected $layoutID = 1;


	/**
	 * Form object
	 *
	 * @var object of type \StudyBuddy\Forms\Form
	 */
	protected $oForm;


	/**
	 * Existing API data in case this is
	 * an edit of client
	 *
	 * @var object of type MongoDoc representing
	 * the Api client
	 */
	protected $oApi;


	protected function main(){
		$this->setApi();
		$email = $this->oRegistry->Viewer->email;
		$this->oForm = new \StudyBuddy\Forms\Apiclient($this->oRegistry);

		if($this->oForm->isSubmitted() && $this->oForm->validate()){
			d('$this->oApi: '.print_r($this->oApi->getArrayCopy(), 1));
			$this->save();
			$this->oRegistry->Dispatcher->post($this->oForm, 'onApiClientSave');
			$url = '/index.php?a=viewapp&app_id='.$this->oApi['_id'];
			Responder::redirectToPage($url);
		} else {
			$this->setForm();
			$this->aPageVars['body'] = $this->oForm->getForm();
		}
	}


	/**
	 * Instanticate $this->oApi object
	 * it will either contain empty values
	 * in case this is new registration
	 * or will have values from previous
	 * application
	 *
	 * @return object $this
	 */
	protected function setApi(){
		$appid = $this->oRequest->get('app_id', 'i', null);
		$this->oApi = Clientdata::factory($this->oRegistry);
		if($appid){

			$a = $this->oRegistry->Mongo->API_CLIENTS->findOne(array('_id' => $appid, 'i_uid' => $this->oRegistry->Viewer->getUid()));
			if(!empty($a)){
				$this->oApi->reload($a);
			} else {
				d('not found by id '.$appid);
			}
		}

		return $this;
	}


	/**
	 * Populate form values with
	 * existing data from oApi object
	 * if this is a new registration then
	 * $this->oApi has empty array as its data
	 * and all values will be empty (just as we expect)
	 *
	 * @return object $this
	 */
	protected function setForm(){
		$c = Captcha::factory($this->oRegistry)->getCaptchaBlock();
		$id = $this->oRequest->get('app_id', 'i', 0);
		$this->oForm->formTitle = $this->aPageVars['title'] = (empty($id)) ?  'Register an Application' : 'Edit Application details';

		$this->oForm->setVar('captcha', $c);
		$this->oForm->app_id 	 = (int)$this->oApi['_id'];
		$this->oForm->app_name 	 = $this->oApi['app_name'];
		$this->oForm->appsite    = $this->oApi['appsite'];
		$this->oForm->company    = $this->oApi['company'];
		$this->oForm->company    = $this->oApi['company'];
		$this->oForm->app_type   = $this->oApi['app_type'];
		$this->oForm->about      = $this->oApi['about'];
		$this->oForm->icon_image = $this->oApi->getIcon(false);

		return $this;
	}


	/**
	 * Save the submitted form values
	 * by setting the $this->oApi object
	 * and then calling insert() or save() on it
	 *
	 * @return object $this
	 *
	 */
	protected function save(){
		$isUpdate = false;
		$vals = $this->oForm->getSubmittedValues();
		d('vals: '.print_r($vals, 1));

		$appid = (int)$vals['app_id'];
		if($appid > 0){
			$isUpdate = true;
			d('has appid, editing mode');
			$this->validateAppIdOwnership($appid);
		} else {
			/**
			 * Auto-generate app_id
			 * Use USERS auto-increment value
			 * because we can then store the image in the same
			 * way we store avatar - in the same directory
			 * using hex based path.
			 *
			 */
			$appid = $this->oRegistry->Incrementor->nextValue('USERS');
		}

		d('$appid: '.$appid);
		$this->oApi['_id'] 		 = $appid;
		$this->oApi['i_uid']     = $this->oRegistry->Viewer->getUid();
		$this->oApi['app_name']  = (string)$this->oRequest->getUTF8('app_name')->trim()->stripTags();
		$this->oApi['appsite']   = (string)$this->oRequest->getUTF8('appsite')->trim()->stripTags();
		$this->oApi['company']   = (string)$this->oRequest->getUTF8('company')->trim()->stripTags();
		$this->oApi['app_type']  = (string)$this->oRequest->getUTF8('app_type')->trim()->stripTags();
		$this->oApi['about']  	 = (string)$this->oRequest->getUTF8('about')->trim()->stripTags();
		$this->oApi['api_key'] 	 = $appid.'.'.String::makeRandomString(12);

		$this->parseIcon();

		/**
		 * Ensure that app is a unique field
		 * app is the name of application
		 */
		$coll = $this->oRegistry->Mongo->API_CLIENTS;
		$coll->ensureIndex(array('app_name' => 1), array('unique' => true));
		$coll->ensureIndex(array('api_key' => 1), array('unique' => true));
		$coll->ensureIndex(array('i_uid' => 1));

		try{
			if($isUpdate){
				d('cp');
				$this->oApi['edited_time'] = date('F j, Y g:i a T');
				$this->oApi['edit_ip'] = Request::getIP();
				$res = $this->oApi->save();
			} else {
				d('cp');
				$this->oApi['created_time'] = date('F j, Y g:i a T');
				$this->oApi['ip'] = Request::getIP();
				$res = $this->oApi->insert();
			}
		} catch (\Exception $e){
			exit($e->getMessage());
		}

		d('$res: '.$res);

		return $this;
	}


	/**
	 * Verify that the appid is owned by
	 * the same user as Viewer
	 *
	 * @param int $appid
	 */
	protected function validateAppIdOwnership($appid){

		$a = $this->oRegistry->Mongo->API_CLIENTS->findOne(array('_id' => $appid));
		if($a['i_uid'] !==  $this->oRegistry->Viewer->getUid()){
			throw new \StudyBuddy\Exception('You do not have permission to edit this application');
		}

		return $this;
	}


	/**
	 * If use has uploaded an Icon for the app
	 * then parse it and add to oApi object
	 *
	 * @return object $this
	 */
	protected function parseIcon(){
		d('cp');

		if(!$this->oForm->hasUploads() || (null === $tempPath = $this->oForm->getUploadedFile('icon'))){
			d('Icon not uploaded');

			return $this;
		}

		
		d('$tempPath: '.$tempPath);

		IconParser::addIcon($this->oApi, $tempPath);

		return $this;
	}

}
